/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package funciones;

import AplicacionMVC.Vistas;
import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.io.PrintStream;

/**
 *
 * @author Administrador
 */
public class HebraRedireccion implements Runnable{
    private boolean quit;
    private final PipedInputStream pin;
    private final PipedInputStream perr;
    private Vistas ventana;
    private Thread hebraOUT;
    private Thread hebraERR;
    public HebraRedireccion(Vistas ventana){
            quit=false;
            this.ventana=ventana;
            pin= new PipedInputStream();
            perr= new PipedInputStream();
        // REDIRECCION DE SYSTEM.OUT
            try{
                PipedOutputStream pout=new PipedOutputStream(pin);
                System.setOut(new PrintStream(pout,true));
            }catch (java.io.IOException io){
			ventana.setListModelConsolaError("No se pudo redireccionar STDOUT a la CONSOLA: "+io.getMessage());
            }catch (SecurityException se){
			ventana.setListModelConsolaError("No se pudo redireccionar STDOUT a la CONSOLA: "+se.getMessage());
            }
            // REDIRECCIÓN DE SYSTEM.ERR
            try{
                PipedOutputStream pouterr=new PipedOutputStream(perr);
                System.setErr(new PrintStream(pouterr,true));
            }catch (java.io.IOException io){
                ventana.setListModelConsolaError("No se pudo redireccionar STDERR a la CONSOLA: "+io.getMessage());
            }catch (SecurityException se){
                ventana.setListModelConsolaError("No se pudo redireccionar STDERR a la CONSOLA: "+se.getMessage());
            }      

		// Se lanzan las 2 hebras que leeran de cada uno de los streams
                
		hebraOUT=new Thread(this);
                hebraOUT.setDaemon(true);
		hebraOUT.start();
		//
		hebraERR=new Thread(this);
		hebraERR.setDaemon(true);
		hebraERR.start();
      
    }
    
    @Override
    public synchronized void run(){
        try{
            while (Thread.currentThread()==hebraOUT){
                try{this.wait(100);}catch(InterruptedException ie){}
                if (pin.available()!=0){
                    String input=this.readLine(pin);
                    ventana.setListModelConsola(input);
                }
                if (quit) return;
            }

            while (Thread.currentThread()==hebraERR){
                try{this.wait(100);}catch(InterruptedException ie){}
                if (perr.available()!=0){
                    String input=this.readLine(perr);
                    ventana.setListModelConsolaError(input);
                }
                if (quit) return;
            }
        }catch (Exception e){
            ventana.setListModelConsolaError("\nError interno de la Consola.");
            ventana.setListModelConsolaError("El error es: "+e);
        }
    }
    
    public synchronized String readLine(PipedInputStream in) throws IOException{
        String input="";
        do{
            int available=in.available();
            if (available==0) break;
            byte b[]=new byte[available];
            in.read(b);
            input=input+new String(b,0,b.length);
        }while( !input.endsWith("\n") &&  !input.endsWith("\r\n"));
        return input;
    }
    
    public synchronized void matarHebras(){
		quit=true;
		this.notifyAll(); // stop all threads
		try { hebraOUT.join(1000);pin.close();   } catch (Exception e){}
		try { hebraERR.join(1000);perr.close(); } catch (Exception e){}
    }
}
